package com.chucang.shucang.usr.service.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.text.CharSequenceUtil;
import cn.hutool.core.util.RandomUtil;
import cn.hutool.crypto.SmUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.conditions.query.LambdaQueryChainWrapper;
import com.chucang.shucang.common.base.constant.CommonConstant;
import com.chucang.shucang.common.base.constant.SecurityConstant;
import com.chucang.shucang.common.base.exception.FastException;
import com.chucang.shucang.common.base.page.PageData;
import com.chucang.shucang.common.base.page.PageQuery;
import com.chucang.shucang.common.base.redis.RedisUtil;
import com.chucang.shucang.common.base.service.impl.CrudServiceImpl;
import com.chucang.shucang.common.base.utils.OpsUtil;
import com.chucang.shucang.common.base.utils.R;
import com.chucang.shucang.usr.constant.UsrCacheConstant;
import com.chucang.shucang.usr.constant.UsrCommonConstant;
import com.chucang.shucang.usr.dao.UserBaseDao;
import com.chucang.shucang.usr.dto.UserBaseDTO;
import com.chucang.shucang.usr.entity.UserBaseEntity;
import com.chucang.shucang.usr.entity.UserBlindBoxHoldEntity;
import com.chucang.shucang.usr.entity.UserCollectionHoldEntity;
import com.chucang.shucang.usr.feign.PmsService;
import com.chucang.shucang.usr.feign.vo.BlindBoxBaseEntity;
import com.chucang.shucang.usr.feign.vo.CollectionBaseEntity;
import com.chucang.shucang.usr.service.UserBaseService;
import com.chucang.shucang.usr.service.UserBlindBoxHoldService;
import com.chucang.shucang.usr.service.UserCollectionHoldService;
import com.chucang.shucang.usr.vo.*;
import com.chucang.shucang.usr.vo.query.UserOnSaleProductQuery;
import com.chucang.shucang.usr.vo.query.UserSoldProductQuery;
import lombok.RequiredArgsConstructor;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;


/**
 * 用户基础信息表
 *
 * @author flitsneak flitsneak@gmail.com
 * @since 1.0.0 2022-09-12
 */
@Service
@RequiredArgsConstructor
public class UserBaseServiceImpl extends CrudServiceImpl<UserBaseDao, UserBaseEntity, UserBaseDTO> implements UserBaseService {

    private final UserBlindBoxHoldService userBlindBoxHoldService;
    private final UserCollectionHoldService userCollectionHoldService;
    private final RedisUtil redisUtil;
    private final PmsService pmsService;
    private final ThreadPoolTaskExecutor usrExecutor;

    @Override
    public UserBaseEntity getByInviteCode(String inviteCode) {
        return new LambdaQueryChainWrapper<>(this.baseMapper)
                .eq(UserBaseEntity::getInviteCode, inviteCode)
                .select()
                .one();
    }

    @Override
    public UserBaseEntity getByMobile(String mobile) {
        return new LambdaQueryChainWrapper<>(this.baseMapper)
                .eq(UserBaseEntity::getCellPhoneNum, mobile)
                .select()
                .one();
    }

    @Override
    public PageData<UserSoldProductResVO> soldProductPage(UserSoldProductQuery userSoldProductQuery) throws ExecutionException, InterruptedException {
        int page = 1;
        int limit = userSoldProductQuery.getLimit() * userSoldProductQuery.getPage();
        int rawPage = userSoldProductQuery.getPage();
        int rawLimit = userSoldProductQuery.getLimit();
        int offsetBegin = (rawPage - 1) * rawLimit;
        int offsetEnd = rawPage * rawLimit;
        userSoldProductQuery.setPage(page);
        userSoldProductQuery.setLimit(limit);

        CompletableFuture<IPage<UserCollectionHoldEntity>> collectionFuture = CompletableFuture.supplyAsync(() -> {
            LambdaQueryWrapper<UserCollectionHoldEntity> collectionLambdaQueryWrapper = new LambdaQueryWrapper<>();
            collectionLambdaQueryWrapper
                    .eq(UserCollectionHoldEntity::getUserId, userSoldProductQuery.getId())
                    .eq(UserCollectionHoldEntity::getStatus, UsrCommonConstant.COLLECTION_SOLD)
                    .orderByDesc(UserCollectionHoldEntity::getUpdateTime);
            return userCollectionHoldService.page(
                    new PageQuery<UserCollectionHoldEntity>().getPage(userSoldProductQuery),
                    collectionLambdaQueryWrapper
            );
        }, usrExecutor);

        CompletableFuture<IPage<UserBlindBoxHoldEntity>> blindBoxFuture = CompletableFuture.supplyAsync(() -> {
            LambdaQueryWrapper<UserBlindBoxHoldEntity> blindBoxLambdaQueryWrapper = new LambdaQueryWrapper<>();
            blindBoxLambdaQueryWrapper
                    .eq(UserBlindBoxHoldEntity::getUserId, userSoldProductQuery.getId())
                    .eq(UserBlindBoxHoldEntity::getStatus, UsrCommonConstant.BLIND_BOX_SOLD)
                    .orderByDesc(UserBlindBoxHoldEntity::getUpdateTime);
            return userBlindBoxHoldService.page(
                    new PageQuery<UserBlindBoxHoldEntity>().getPage(userSoldProductQuery),
                    blindBoxLambdaQueryWrapper
            );
        }, usrExecutor);

        return collectionFuture.thenCombineAsync(blindBoxFuture, (cp, bp) -> {
                    //藏品set
                    Set<Long> collectionSet = new HashSet<>(32);
                    //盲盒set
                    Set<Long> blindBoxSet = new HashSet<>(32);
                    if (CollUtil.isEmpty(cp.getRecords()) && CollUtil.isEmpty(bp.getRecords())) {
                        return new PageData<UserSoldProductResVO>(Collections.emptyList(), 0);
                    }
                    if ((cp.getTotal() + bp.getTotal()) < offsetBegin) {
                        return new PageData<UserSoldProductResVO>(Collections.emptyList(), 0);
                    }
                    if (!CollUtil.isEmpty(cp.getRecords()) && !CollUtil.isEmpty(bp.getRecords())) {
                        List<UserSoldProductResVO> userSoldProductResVOList = new ArrayList<>(32);
                        this.collectSoldCollectionInfo(userSoldProductResVOList, cp.getRecords());

                        this.collectionSoldBlindBoxInfo(userSoldProductResVOList, bp.getRecords());

                        userSoldProductResVOList.sort(Comparator.comparing(UserSoldProductResVO::getCreateTime, Comparator.reverseOrder()));
                        List<UserSoldProductResVO> soldProductResVOS = userSoldProductResVOList.subList(offsetBegin, Math.min(userSoldProductResVOList.size(), offsetEnd));
                        //获取基础信息
                        soldProductResVOS.forEach(cc -> {
                            if (cc.getProductType() == UsrCommonConstant.COLLECTION) {
                                collectionSet.add(cc.getProductId());
                            } else if (cc.getProductType() == UsrCommonConstant.BLIND_BOX) {
                                blindBoxSet.add(cc.getProductId());
                            }
                        });
                        if (!CollUtil.isEmpty(collectionSet)) {
                            this.setUserSoldCollectionInfo(soldProductResVOS, collectionSet);
                        }

                        if (!CollUtil.isEmpty(blindBoxSet)) {
                            this.setUserSoldBlindBoxInfo(soldProductResVOS, blindBoxSet);
                        }
                        return new PageData<>(soldProductResVOS, cp.getTotal() + bp.getTotal());
                    }
                    if (CollUtil.isEmpty(cp.getRecords())) {
                        List<UserSoldProductResVO> userSoldProductResVOList = new ArrayList<>(32);
                        this.collectionSoldBlindBoxInfo(userSoldProductResVOList, bp.getRecords());
                        List<UserSoldProductResVO> soldProductResVOS = userSoldProductResVOList.subList(offsetBegin, Math.min(userSoldProductResVOList.size(), offsetEnd));
                        //获取基础信息
                        soldProductResVOS.forEach(cc ->
                                blindBoxSet.add(cc.getProductId())
                        );
                        if (!CollUtil.isEmpty(blindBoxSet)) {
                            this.setUserSoldBlindBoxInfo(soldProductResVOS, blindBoxSet);
                        }
                        return new PageData<>(soldProductResVOS, cp.getTotal() + bp.getTotal());
                    }

                    if (CollUtil.isEmpty(bp.getRecords())) {
                        List<UserSoldProductResVO> userSoldProductResVOList = new ArrayList<>(32);
                        this.collectSoldCollectionInfo(userSoldProductResVOList, cp.getRecords());
                        List<UserSoldProductResVO> soldProductResVOS = userSoldProductResVOList.subList(offsetBegin, Math.min(userSoldProductResVOList.size(), offsetEnd));
                        //获取基础信息
                        soldProductResVOS.forEach(cc ->
                                collectionSet.add(cc.getProductId())
                        );
                        if (!CollUtil.isEmpty(collectionSet)) {
                            this.setUserSoldCollectionInfo(soldProductResVOS, collectionSet);
                        }
                        return new PageData<>(soldProductResVOS, cp.getTotal() + bp.getTotal());
                    }
                    return new PageData<UserSoldProductResVO>(Collections.emptyList(), 0);
                }, usrExecutor)
                .get();

    }

    @Override
    public PageData<UserOnSaleProductResVO> onSaleProductPage(UserOnSaleProductQuery userOnSaleProductQuery) throws ExecutionException, InterruptedException {
        int page = 1;
        int limit = userOnSaleProductQuery.getLimit() * userOnSaleProductQuery.getPage();
        int rawPage = userOnSaleProductQuery.getPage();
        int rawLimit = userOnSaleProductQuery.getLimit();
        int offsetBegin = (rawPage - 1) * rawLimit;
        int offsetEnd = rawPage * rawLimit;
        userOnSaleProductQuery.setPage(page);
        userOnSaleProductQuery.setLimit(limit);

        CompletableFuture<IPage<UserCollectionHoldEntity>> collectionFuture = CompletableFuture.supplyAsync(() -> {
            LambdaQueryWrapper<UserCollectionHoldEntity> collectionLambdaQueryWrapper = new LambdaQueryWrapper<>();
            collectionLambdaQueryWrapper
                    .eq(UserCollectionHoldEntity::getUserId, userOnSaleProductQuery.getId())
                    .eq(UserCollectionHoldEntity::getStatus, UsrCommonConstant.COLLECTION_CONSIGN)
                    .orderByDesc(UserCollectionHoldEntity::getUpdateTime);
            return userCollectionHoldService.page(
                    new PageQuery<UserCollectionHoldEntity>().getPage(userOnSaleProductQuery),
                    collectionLambdaQueryWrapper
            );
        }, usrExecutor);

        CompletableFuture<IPage<UserBlindBoxHoldEntity>> blindBoxFuture = CompletableFuture.supplyAsync(() -> {
            LambdaQueryWrapper<UserBlindBoxHoldEntity> blindBoxLambdaQueryWrapper = new LambdaQueryWrapper<>();
            blindBoxLambdaQueryWrapper
                    .eq(UserBlindBoxHoldEntity::getUserId, userOnSaleProductQuery.getId())
                    .eq(UserBlindBoxHoldEntity::getStatus, UsrCommonConstant.BLIND_BOX_CONSIGN)
                    .orderByDesc(UserBlindBoxHoldEntity::getUpdateTime);
            return userBlindBoxHoldService.page(
                    new PageQuery<UserBlindBoxHoldEntity>().getPage(userOnSaleProductQuery),
                    blindBoxLambdaQueryWrapper
            );
        }, usrExecutor);

        return collectionFuture.thenCombineAsync(blindBoxFuture, (cp, bp) -> {
                    //藏品set
                    Set<Long> collectionSet = new HashSet<>(32);
                    //盲盒set
                    Set<Long> blindBoxSet = new HashSet<>(32);
                    if (CollUtil.isEmpty(cp.getRecords()) && CollUtil.isEmpty(bp.getRecords())) {
                        return new PageData<UserOnSaleProductResVO>(Collections.emptyList(), 0);
                    }
                    if ((cp.getTotal() + bp.getTotal()) < offsetBegin) {
                        return new PageData<UserOnSaleProductResVO>(Collections.emptyList(), 0);
                    }
                    if (!CollUtil.isEmpty(cp.getRecords()) && !CollUtil.isEmpty(bp.getRecords())) {
                        List<UserOnSaleProductResVO> userOnSaleProductResVOList = new ArrayList<>(32);
                        this.collectOnSaleCollectionInfo(userOnSaleProductResVOList, cp.getRecords());

                        this.collectionOnSaleBlindBoxInfo(userOnSaleProductResVOList, bp.getRecords());

                        userOnSaleProductResVOList.sort(Comparator.comparing(UserOnSaleProductResVO::getCreateTime, Comparator.reverseOrder()));
                        List<UserOnSaleProductResVO> onSaleProductResVOS = userOnSaleProductResVOList.subList(offsetBegin, Math.min(userOnSaleProductResVOList.size(), offsetEnd));
                        //获取基础信息
                        onSaleProductResVOS.forEach(cc -> {
                            if (cc.getProductType() == UsrCommonConstant.COLLECTION) {
                                collectionSet.add(cc.getProductId());
                            } else if (cc.getProductType() == UsrCommonConstant.BLIND_BOX) {
                                blindBoxSet.add(cc.getProductId());
                            }
                        });
                        if (!CollUtil.isEmpty(collectionSet)) {
                            this.setUserOnSaleCollectionInfo(onSaleProductResVOS, collectionSet);
                        }

                        if (!CollUtil.isEmpty(blindBoxSet)) {
                            this.setUserOnSaleBlindBoxInfo(onSaleProductResVOS, blindBoxSet);
                        }
                        return new PageData<>(onSaleProductResVOS, cp.getTotal() + bp.getTotal());
                    }
                    if (CollUtil.isEmpty(cp.getRecords())) {
                        List<UserOnSaleProductResVO> userOnSaleProductResVOList = new ArrayList<>(32);
                        this.collectionOnSaleBlindBoxInfo(userOnSaleProductResVOList, bp.getRecords());
                        List<UserOnSaleProductResVO> onSaleProductResVOS = userOnSaleProductResVOList.subList(offsetBegin, Math.min(userOnSaleProductResVOList.size(), offsetEnd));
                        //获取基础信息
                        onSaleProductResVOS.forEach(cc ->
                                blindBoxSet.add(cc.getProductId())
                        );
                        if (!CollUtil.isEmpty(blindBoxSet)) {
                            this.setUserOnSaleBlindBoxInfo(onSaleProductResVOS, blindBoxSet);
                        }
                        return new PageData<>(onSaleProductResVOS, cp.getTotal() + bp.getTotal());
                    }

                    if (CollUtil.isEmpty(bp.getRecords())) {
                        List<UserOnSaleProductResVO> userOnSaleProductResVOList = new ArrayList<>(32);
                        this.collectOnSaleCollectionInfo(userOnSaleProductResVOList, cp.getRecords());
                        List<UserOnSaleProductResVO> onSaleProductResVOS = userOnSaleProductResVOList.subList(offsetBegin, Math.min(userOnSaleProductResVOList.size(), offsetEnd));
                        //获取基础信息
                        onSaleProductResVOS.forEach(cc ->
                                collectionSet.add(cc.getProductId())
                        );
                        if (!CollUtil.isEmpty(collectionSet)) {
                            this.setUserOnSaleCollectionInfo(onSaleProductResVOS, collectionSet);
                        }
                        return new PageData<>(onSaleProductResVOS, cp.getTotal() + bp.getTotal());
                    }
                    return new PageData<UserOnSaleProductResVO>(Collections.emptyList(), 0);
                }, usrExecutor)
                .get();
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean withdrawProductConsign(UserWithdrawProductConsignVO userWithdrawProductConsignVO) {
        if (userWithdrawProductConsignVO.getProductType() == UsrCommonConstant.COLLECTION) {
            LambdaQueryWrapper<UserCollectionHoldEntity> lambdaQueryWrapper = new LambdaQueryWrapper<>();
            lambdaQueryWrapper
                    .eq(UserCollectionHoldEntity::getCollectionId, userWithdrawProductConsignVO.getProductId())
                    .eq(UserCollectionHoldEntity::getUserId, userWithdrawProductConsignVO.getUserId())
                    .eq(UserCollectionHoldEntity::getSerialNum, userWithdrawProductConsignVO.getSerialNum())
                    .select();
            UserCollectionHoldEntity one = userCollectionHoldService.getOne(lambdaQueryWrapper);
            one.setStatus(UsrCommonConstant.COLLECTION_HOLD);
            //更新商城状态
            R<String> r = pmsService.withdrawCollectionConsign(one.getConsignId(), SecurityConstant.FROM_IN);
            OpsUtil.of(r).assertCode(CommonConstant.SUCCESS, e -> new FastException("取消藏品寄售异常"));
            return userCollectionHoldService.updateById(one);
        } else if (userWithdrawProductConsignVO.getProductType() == UsrCommonConstant.BLIND_BOX) {
            LambdaQueryWrapper<UserBlindBoxHoldEntity> lambdaQueryWrapper = new LambdaQueryWrapper<>();
            lambdaQueryWrapper
                    .eq(UserBlindBoxHoldEntity::getBbId, userWithdrawProductConsignVO.getProductId())
                    .eq(UserBlindBoxHoldEntity::getUserId, userWithdrawProductConsignVO.getUserId())
                    .eq(UserBlindBoxHoldEntity::getSerialNum, userWithdrawProductConsignVO.getSerialNum())
                    .select();
            UserBlindBoxHoldEntity one = userBlindBoxHoldService.getOne(lambdaQueryWrapper);
            one.setStatus(UsrCommonConstant.BLIND_BOX_HOLD);
            //更新商城状态
            R<String> r = pmsService.withdrawBlindBoxConsign(one.getConsignId(), SecurityConstant.FROM_IN);
            OpsUtil.of(r).assertCode(CommonConstant.SUCCESS, e -> new FastException("取消盲盒寄售异常"));
            return userBlindBoxHoldService.updateById(one);
        } else {
            return false;
        }
    }

    @Override
    public boolean setSecPassword(UserSetSecPasswordVO userSetSecPasswordVO) {
        UserBaseEntity byId = this.getById(userSetSecPasswordVO.getUserId());
        if (!CharSequenceUtil.isBlank(byId.getSecPassword())) {
            return true;
        }
        LambdaUpdateWrapper<UserBaseEntity> updateWrapper = new LambdaUpdateWrapper<>();
        updateWrapper.eq(UserBaseEntity::getId, userSetSecPasswordVO.getUserId())
                .set(UserBaseEntity::getSecPassword, SmUtil.sm3(userSetSecPasswordVO.getSecPassword()));
        return this.update(updateWrapper);
    }

    @Override
    public String checkSecPassword(UserCheckSecPasswordVO userCheckSecPasswordVO) {
        UserBaseEntity byId = this.getById(userCheckSecPasswordVO.getUserId());
        if (byId.getSecPassword().equals(SmUtil.sm3(userCheckSecPasswordVO.getSecPassword()))) {
            String checkCode = RandomUtil.randomNumbers(6);
            redisUtil.setValue(String.format(UsrCacheConstant.USER_CHECK_SEC_PASSWORD, userCheckSecPasswordVO.getUserId()), checkCode, 3, TimeUnit.MINUTES);
            return checkCode;
        } else {
            return null;
        }
    }

    private void setUserSoldCollectionInfo(List<UserSoldProductResVO> soldProductResVOS, Set<Long> collectionSet) {
        Map<Long, String> ccHashMap = new HashMap<>(32);
        Map<Long, String> ccCoverPicHashMap = new HashMap<>(32);
        Map<Long, Integer> ccTotalHashMap = new HashMap<>(32);
        collectionSet
                .stream()
                .map(cs -> CompletableFuture.supplyAsync(() -> {
                            R<CollectionBaseEntity> baseInfo = pmsService
                                    .getCollectionBaseInfo(cs, SecurityConstant.FROM_IN);
                            return OpsUtil
                                    .of(baseInfo)
                                    .assertDataNotNull(e -> new FastException("藏品信息为空！"))
                                    .getData()
                                    .get();
                        }, usrExecutor
                ))
                .collect(Collectors.toList())
                .stream()
                .map(CompletableFuture::join)
                .collect(Collectors.toList())
                .forEach(ccs -> {
                    ccHashMap.put(ccs.getId(), ccs.getDcName());
                    ccCoverPicHashMap.put(ccs.getId(), ccs.getCoverPicture());
                    ccTotalHashMap.put(ccs.getId(), ccs.getTotalNum());
                });
        soldProductResVOS.forEach(spc -> {
            if (spc.getProductType() == UsrCommonConstant.COLLECTION) {
                spc.setProductName(ccHashMap.get(spc.getProductId()));
                spc.setCoverPicture(ccCoverPicHashMap.get(spc.getProductId()));
                spc.setProductSerialNum(String.format(UsrCommonConstant.SERIAL_NUM, spc.getSerialNum(), ccTotalHashMap.get(spc.getProductId())));
            }
        });
    }

    private void setUserOnSaleCollectionInfo(List<UserOnSaleProductResVO> onSaleProductResVOS, Set<Long> collectionSet) {
        Map<Long, String> ccHashMap = new HashMap<>(32);
        Map<Long, String> ccCoverPicHashMap = new HashMap<>(32);
        Map<Long, Integer> ccTotalHashMap = new HashMap<>(32);
        collectionSet
                .stream()
                .map(cs -> CompletableFuture.supplyAsync(() -> {
                            R<CollectionBaseEntity> baseInfo = pmsService
                                    .getCollectionBaseInfo(cs, SecurityConstant.FROM_IN);
                            return OpsUtil
                                    .of(baseInfo)
                                    .assertDataNotNull(e -> new FastException("藏品信息为空！"))
                                    .getData()
                                    .get();
                        }, usrExecutor
                ))
                .collect(Collectors.toList())
                .stream()
                .map(CompletableFuture::join)
                .collect(Collectors.toList())
                .forEach(ccs -> {
                    ccHashMap.put(ccs.getId(), ccs.getDcName());
                    ccCoverPicHashMap.put(ccs.getId(), ccs.getCoverPicture());
                    ccTotalHashMap.put(ccs.getId(), ccs.getTotalNum());
                });
        onSaleProductResVOS.forEach(spc -> {
            if (spc.getProductType() == UsrCommonConstant.COLLECTION) {
                spc.setProductName(ccHashMap.get(spc.getProductId()));
                spc.setCoverPicture(ccCoverPicHashMap.get(spc.getProductId()));
                spc.setProductSerialNum(String.format(UsrCommonConstant.SERIAL_NUM, spc.getSerialNum(), ccTotalHashMap.get(spc.getProductId())));
            }
        });
    }

    private void setUserSoldBlindBoxInfo(List<UserSoldProductResVO> soldProductResVOS, Set<Long> blindBoxSet) {
        Map<Long, String> bbHashMap = new HashMap<>(32);
        Map<Long, String> bbCoverPicHashMap = new HashMap<>(32);
        Map<Long, Integer> bbTotalHashMap = new HashMap<>(32);
        blindBoxSet
                .stream()
                .map(bs -> CompletableFuture.supplyAsync(() -> {
                            R<BlindBoxBaseEntity> baseInfo = pmsService
                                    .getBlindBoxBaseInfo(bs, SecurityConstant.FROM_IN);
                            return OpsUtil
                                    .of(baseInfo)
                                    .assertDataNotNull(e -> new FastException("盲盒信息为空！"))
                                    .getData()
                                    .get();
                        }, usrExecutor
                ))
                .collect(Collectors.toList())
                .stream()
                .map(CompletableFuture::join)
                .collect(Collectors.toList())
                .forEach(bbs -> {
                    bbHashMap.put(bbs.getId(), bbs.getBbName());
                    bbCoverPicHashMap.put(bbs.getId(), bbs.getCoverPicture());
                    bbTotalHashMap.put(bbs.getId(), bbs.getTotalNum());
                });
        soldProductResVOS.forEach(sps -> {
            if (sps.getProductType() == UsrCommonConstant.BLIND_BOX) {
                sps.setProductName(bbHashMap.get(sps.getProductId()));
                sps.setCoverPicture(bbCoverPicHashMap.get(sps.getProductId()));
                sps.setProductSerialNum(String.format(UsrCommonConstant.SERIAL_NUM, sps.getSerialNum(), bbTotalHashMap.get(sps.getProductId())));
            }
        });
    }

    private void setUserOnSaleBlindBoxInfo(List<UserOnSaleProductResVO> onSaleProductResVOS, Set<Long> blindBoxSet) {
        Map<Long, String> bbHashMap = new HashMap<>(32);
        Map<Long, String> bbCoverPicHashMap = new HashMap<>(32);
        Map<Long, Integer> bbTotalHashMap = new HashMap<>(32);
        blindBoxSet
                .stream()
                .map(bs -> CompletableFuture.supplyAsync(() -> {
                            R<BlindBoxBaseEntity> baseInfo = pmsService
                                    .getBlindBoxBaseInfo(bs, SecurityConstant.FROM_IN);
                            return OpsUtil
                                    .of(baseInfo)
                                    .assertDataNotNull(e -> new FastException("盲盒信息为空！"))
                                    .getData()
                                    .get();
                        }, usrExecutor
                ))
                .collect(Collectors.toList())
                .stream()
                .map(CompletableFuture::join)
                .collect(Collectors.toList())
                .forEach(bbs -> {
                    bbHashMap.put(bbs.getId(), bbs.getBbName());
                    bbCoverPicHashMap.put(bbs.getId(), bbs.getCoverPicture());
                    bbTotalHashMap.put(bbs.getId(), bbs.getTotalNum());
                });
        onSaleProductResVOS.forEach(sps -> {
            if (sps.getProductType() == UsrCommonConstant.BLIND_BOX) {
                sps.setProductName(bbHashMap.get(sps.getProductId()));
                sps.setCoverPicture(bbCoverPicHashMap.get(sps.getProductId()));
                sps.setProductSerialNum(String.format(UsrCommonConstant.SERIAL_NUM, sps.getSerialNum(), bbTotalHashMap.get(sps.getProductId())));
            }
        });
    }

    private void collectSoldCollectionInfo(List<UserSoldProductResVO> userSoldProductResVOList, List<UserCollectionHoldEntity> userCollectionHoldEntities) {
        userCollectionHoldEntities.forEach(c -> {
            UserSoldProductResVO userSoldProductResVO = new UserSoldProductResVO();
            userSoldProductResVO.setProductId(c.getCollectionId());
            userSoldProductResVO.setSerialNum(c.getSerialNum());
            userSoldProductResVO.setSellingPrice(c.getSellingPrice());
            userSoldProductResVO.setProductType(UsrCommonConstant.COLLECTION);
            userSoldProductResVO.setCreateTime(c.getCreateTime());
            userSoldProductResVOList.add(userSoldProductResVO);
        });
    }

    private void collectOnSaleCollectionInfo(List<UserOnSaleProductResVO> userOnSaleProductResVOList, List<UserCollectionHoldEntity> userCollectionHoldEntities) {
        userCollectionHoldEntities.forEach(c -> {
            UserOnSaleProductResVO userOnSaleProductResVO = new UserOnSaleProductResVO();
            userOnSaleProductResVO.setProductId(c.getCollectionId());
            userOnSaleProductResVO.setSerialNum(c.getSerialNum());
            userOnSaleProductResVO.setSellingPrice(c.getSellingPrice());
            userOnSaleProductResVO.setProductType(UsrCommonConstant.COLLECTION);
            userOnSaleProductResVO.setCreateTime(c.getCreateTime());
            userOnSaleProductResVOList.add(userOnSaleProductResVO);
        });
    }

    private void collectionSoldBlindBoxInfo(List<UserSoldProductResVO> userSoldProductResVOList, List<UserBlindBoxHoldEntity> userBlindBoxHoldEntities) {
        userBlindBoxHoldEntities.forEach(b -> {
            UserSoldProductResVO userSoldProductResVO = new UserSoldProductResVO();
            userSoldProductResVO.setProductId(b.getBbId());
            userSoldProductResVO.setSerialNum(b.getSerialNum());
            userSoldProductResVO.setSellingPrice(b.getSellingPrice());
            userSoldProductResVO.setProductType(UsrCommonConstant.BLIND_BOX);
            userSoldProductResVO.setCreateTime(b.getCreateTime());
            userSoldProductResVOList.add(userSoldProductResVO);
        });
    }

    private void collectionOnSaleBlindBoxInfo(List<UserOnSaleProductResVO> userOnSaleProductResVOList, List<UserBlindBoxHoldEntity> userBlindBoxHoldEntities) {
        userBlindBoxHoldEntities.forEach(b -> {
            UserOnSaleProductResVO userOnSaleProductResVO = new UserOnSaleProductResVO();
            userOnSaleProductResVO.setProductId(b.getBbId());
            userOnSaleProductResVO.setSerialNum(b.getSerialNum());
            userOnSaleProductResVO.setSellingPrice(b.getSellingPrice());
            userOnSaleProductResVO.setProductType(UsrCommonConstant.BLIND_BOX);
            userOnSaleProductResVO.setCreateTime(b.getCreateTime());
            userOnSaleProductResVOList.add(userOnSaleProductResVO);
        });
    }

}